/*
 * mol_efuse.h
 *
 *  Created on: Aug 9, 2016
 *      Author: duobao
 */

#ifndef MOL_EFUSE_H_
#define MOL_EFUSE_H_

#include <linux/io.h>
#include <linux/scatterlist.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/scatterlist.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/bug.h>
#include <linux/completion.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <crypto/if_alg.h>
/****************************************************************************
 * #define section
 *	add constant #define here if any
 ***************************************************************************/
#define IOCTL_EFUSE_CHECK_PRO						0
#define IOCTL_EFUSE_WRITE_KEY						1
#define IOCTL_EFUSE_CHECK_LOCK						2
#define IOCTL_EFUSE_TRANS_KEY						3
#define IOCTL_EFUSE_SWITCH_CPU_KEY_MODE				4
#define IOCTL_EFUSE_SWITCH_EFUSE_KEY_MODE			5
#define IOCTL_EFUSE_CHECK_ERROR						6
#define IOCTL_EFUSE_READ_KEY						7
#define IOCTL_EFUSE_SET_LOCK						8
#define IOCTL_EFUSE_SET_MAP_PARA_4_TO_1					9
#define IOCTL_EFUSE_SET_MAP_PARA_1_TO_1					10
#define IOCTL_EFUSE_CLR_MAP_PARA					11
#define IOCTL_EFUSE_WRITE_BIT               30
#define IOCTL_EFUSE_SET_LOCK_WRITE_DATA     31
#define IOCTL_EFUSE_MEM_CMP                 32
#define IOCTL_EFUSE_WRITE_ENTRY						20
#define IOCTL_EFUSE_READ_ENTRY						21
#define EFUSE_NEED_TRANS	0x55
/****************************************************************************
 * ADT section
 *	add Abstract Data Type definition here
 ***************************************************************************/

struct efuse_status {
	/* bit 1 means could write..0 not write
	 * 64block version: bit0 ~ bit63
	 * 16block version: bit0 ~ bit15
	 */
	u32 protect_bits[2];
	/*
	 * 64block version: bit0: block0 ~ block3	[readlock]
	 *                  bit1: block4 ~ block7	[readlock]
	 *                  ...
	 *                  bit14: block56 ~ block59[readlock]
	 *
	 * 16block version: bit0: block0 ~ block3	[readlock]
	 *                  bit1: block4 ~ block7	[readlock]
	 *                  bit2: block8 ~ block11	[readlock]
	 */
	u32 efuse_apb_lock;
	/*
	 * bit0: aes key0 & key1	[readlock]
	 * bit1: aes key2 & key3	[readlock]
	 * bit2: aes key4 & key5	[readlock]
	 * bit3: aes key6 & key7	[readlock]
	 */
	u32 aes_ahb_lock;
	u32 error;
	/*
	 * bit[i]---map to---block[i]
	 * 64block version: bit0 ~ bit56	[writelock]
	 * 16block version: bit0 ~ bit11	[writelock]
	 */
	u32 efuse_write_lock[2];
};

typedef struct {
	u32 efuse_entry_no; /*from 0 ~ 31*/
	u8 *key_buff;
	u32 key_size;
	u32 trans_key_start_no; /*from 0 ~ 7*/
	u32 trans_key_size; /*max 8*/
	struct efuse_status status;
	u32 bit_pos;
	u32 bit_val;
} EFUSE_INFO;

struct wrap_efuse_obj {
	void *regs;
	struct clk *clk;
	/*write key*/
	u32 efuse_entry_no; /*from 0 ~ 31*/
	u8 *key_buff;
	u32 key_size;
	/*trans key*/
	u32 trans_key_start_no; /*from 0 ~ 7*/
	u32 trans_key_size; /*max 8*/
	/*status*/
	struct efuse_status status;
	u32 open_flag;
	/*add check if need efuse transkey*/
	u32 efuse_trans_flag;
	/* for old driver just check size.
	for have mapping func, should check the adv_info para.*/
	u32 old_size;
	struct af_alg_usr_def old_usr_def;
	/* 64block version or 16block version */
	u32 total_blocks;
};


/****************************************************************************
 *  extern variable declaration section
 ***************************************************************************/

/****************************************************************************
 *  section
 *	add function prototype here if any
 ***************************************************************************/
void efuse_trans_key(struct wrap_efuse_obj *obj, u32 start_no,
	u32 size, struct af_alg_usr_def *p_alg);
bool ades_use_efuse_key(u32 key_size, u32 mode,
	u32 map_size, u32 map[][2], u32 is_enc);
void efuse_read_entry(struct wrap_efuse_obj *obj,
	u32 key, u32 start_entry, u8 *buff, u32 size);
int mol_efuse_secure_check(struct wrap_efuse_obj *obj,
	u32 start_no, u32 size, struct af_alg_usr_def *p_alg);

#endif /* MOL_EFUSE_H_ */
